use std::{collections::HashMap, net::SocketAddr, sync::RwLock};

use crc32fast::Hasher;
use futures::{SinkExt, TryStreamExt};
use serde::{Deserialize, Serialize};
use tokio::{net::TcpStream, sync::mpsc};
use tokio_util::codec::{FramedRead, FramedWrite, LinesCodec};

//use crate::ffi_cs::MyApp;
use crate::tcp::tcpcodec::TcpBody;
use crate::tcp::tcpcodec::TcpMessage;

// use crate::ffi_java::call_java_callback;

pub static TCPCLIENTS: std::sync::LazyLock<RwLock<HashMap<String, Client>>> =
    std::sync::LazyLock::new(|| RwLock::new(HashMap::new()));

// pub static CLIENTS: once_cell::sync::OnceCell<Arc<Mutex<HashMap<String, Client>>>> =  once_cell::sync::OnceCell::new();

// pub static CLIENTS: Arc<Mutex<HashMap<String, Client>>> = Arc::new(Mutex::new(HashMap::new()));
// pub static CHANNEL_MSG: Arc<Mutex<HashMap<String, mpsc::Receiver<String>>>> =
//Arc::new(Mutex::new(HashMap::new()));

#[derive(Serialize, Deserialize, Debug, Clone)]
struct Transform {
    msg: String,
}

#[derive(Debug, Clone)]
pub struct Client {
    write_tx: mpsc::UnboundedSender<String>,
}

#[derive(Default, Debug, Clone)]
pub struct Server {}

impl Server {
    pub fn new() -> Server {
        Default::default()
    }

    pub async fn handler_client(
        &mut self,
        stream: TcpStream,
        addr: SocketAddr,
    ) -> anyhow::Result<()> {
        tokio::spawn(async move {
            log::debug!("ip -> {} connected to server", addr);

            let (stream_reader, stream_writer) = stream.into_split();
            let mut framed_reader = FramedRead::new(stream_reader, LinesCodec::new());
            let mut framed_writer = FramedWrite::new(stream_writer, LinesCodec::new());

            let (http_tx, mut http_rx) = mpsc::unbounded_channel::<String>();

            {
                let mut write_client = TCPCLIENTS.write().unwrap();
                let new_client = Client { write_tx: http_tx };
                write_client
                    .entry(addr.to_string())
                    .or_insert(new_client.clone());
            }

            let mut _paused = false;

            loop {
                tokio::select! {
                                   read_result = framed_reader.try_next() => {
                                       if !_paused {
                                           match read_result {
                                               Ok(data) => {
                                                   match data {
                                                       Some(data) =>{
                                                           log::debug!("ip -> {} received tcp message: ->{:?}", addr,&data);
                                                           handler_revice_msg(addr,data).await;
                                                           //framed_writer.send(&data).await;

                                                       },
                                                       None => {
                                                           log::debug!("ip -> {} disconnected server ", addr);
                                                           let mut write_clients = TCPCLIENTS.write().unwrap();
                                                           write_clients.remove(&addr.to_string());
                                                           log::debug!("ip -> {} by removed", addr);
                                                           break;
                                                       }
                                                   }
                                               },
                                               Err(err) => {
                                                   log::debug!("ip -> {} error {}", addr, err);

                                               }
                                           }
                                       }
                                   },
                                   result1 = http_rx.recv() => {
                                       match result1 {
                                           Some(data) => {
                                               log::debug!("ip -> {} received http message -> {}", addr,data);

                                                if let Err(e) = framed_writer.send(&data).await {
                                                                    log::debug!("ip-> {} send message ->{} error -> {}", addr, &data, e);
                                                       }
                                               /* let hex_ret = hex::decode(&data) ;
                                               match hex_ret {
                                                   Ok(ret)=>{

                                                        let msg =  bytes_to_message(ret);
                                                       match msg {
                                                           Ok(msg) => {
                                                                if let Err(e) = framed_writer.send(msg).await {
                                                                    log::debug!("ip-> {} send message ->{} error -> {}", addr, data, e);
                                                                }
                                                            },
                                                            Err(e) => {
                                                               log::debug!("ip-> {} send message ->{} error -> {}", addr, (data), e);
                                                           }
                                                       }

                                                       if let Err(e) = framed_writer.send(ret).await {
                                                                    log::debug!("ip-> {} send message ->{} error -> {}", addr, data, e);
                                                       }

                                                   },
                                                   Err(err) => {
                                                       log::debug!("ip -> {} hex decode data error {}",addr,err);
                                                   }
                                               }
                */
                                           },
                                           None => {
                                               log::debug!("No data received, waiting...");
                                           }
                                       }
                                   }
                               }
            }
        });

        Ok(())
    }
}

pub async fn send_message_to_client(
    addr: Option<SocketAddr>,
    _type: String,
    message: String,
) -> anyhow::Result<()> {
    let clients = TCPCLIENTS.read().unwrap();

    let clients = clients.clone();

    if let Some(addr) = addr {
        let client = clients.get(&addr.to_string());
        if let Some(cli) = client {
            match cli.write_tx.send(message) {
                Ok(()) => {
                    log::debug!("ip -> {} send  addr msg success ", addr);
                }
                Err(e) => {
                    log::debug!("ip -> {} send msg  addr error  {}", addr, e);
                }
            }
        } else {
            log::debug!("ip -> {} get client not found from cache pool", addr);
        }
    } else {
        for (key, client) in clients {
            let send_result = client.write_tx.send(message.clone());

            match send_result {
                Ok(_) => {
                    log::debug!("ip -> {} send msg success ", key);
                }
                Err(e) => {
                    log::debug!("ip -> {} send msg error  {}", key, e);
                }
            }
        }
    }

    Ok(())
}

pub async fn handler_revice_msg(_addr: SocketAddr, msg: String) {
    // call_java_callback(data.clone());

    //MyApp::rust_send_message_to_csharp(&msg);
}

fn bytes_to_message(bytes: Vec<u8>) -> anyhow::Result<TcpMessage> {
    // 确保字节数据的长度至少能容纳一个消息的最小长度
    if bytes.len() < 9 {
        return Err(anyhow::Error::msg("len error"));
    }

    // 解析消息各个字段
    let package_sequence = bytes[0];
    let equipment_type = bytes[1];
    let equipment_number = bytes[2];
    let message_type = bytes[3];
    let message_length = bytes[4];

    // 确保字节数据长度足够包含整个消息
    let total_length = 5 + message_length as usize;
    if bytes.len() < total_length {
        return Err(anyhow::Error::msg("len error 1 "));
    }

    // 解析消息体
    let message_body = bytes[5..total_length].to_vec();

    let mut header_and_body = vec![0x55, 0xAA];

    header_and_body.extend_from_slice(&message_body);

    // 解析校验和
    let checksum = calculate_checksum(&header_and_body);

    let message_body = message_body
        .iter()
        .map(|body| TcpBody { data: *body })
        .collect::<Vec<TcpBody>>();

    Ok(TcpMessage {
        package_sequence,
        equipment_type,
        equipment_number,
        message_type,
        message_length,
        message_body,
        checksum,
    })
}

fn calculate_checksum(message_body: &[u8]) -> [u8; 4] {
    let mut hasher = Hasher::new();
    hasher.update(message_body);
    hasher.finalize().to_be_bytes()
}
